﻿(function ($) {

    $.fn.xslt = function () {
        return this;
    }

    //各浏览器加载xml或xslt
    function loadXML(file) {
        var xmlDoc = null;
        try //Internet Explorer
        {
            xmlDoc = GetXmlDocObject();
            xmlDoc.async = false;
            xmlDoc.load(file);
        }
        catch (e) {
            try //Firefox, Mozilla, Opera, etc.
            {
                xmlDoc = document.implementation.createDocument("", "", null);
                xmlDoc.async = false;
                xmlDoc.load(file);
            }
            catch (e) {
                try //Google Chrome
                {
                    var xmlhttp = new window.XMLHttpRequest();
                    xmlhttp.open("GET", file, false);
                    xmlhttp.send(null);
                    xmlDoc = xmlhttp.responseXML.documentElement;
                }
                catch (e) {
                    error = e.message;
                }
            }
        }
        return xmlDoc;
    }

    function loadXmlForChrome(strXml) {
        ////第一个参数命名空间；第二个参数根节点  
        //var xmlDoc = document.implementation.createDocument("", "", null);
        //xmlDoc.async = false;
        //xmlDoc.load(strXml);

        var p = new DOMParser();
        var xmlDoc = p.parseFromString(strXml, "text/xml");
        return xmlDoc;
    }

    // 使用XSLT把XML文档转换为一个字符串。
    function xml_transformNode(xmlDoc, xslDoc) {
        if (null == xmlDoc) return "";
        if (null == xslDoc) return "";

        if (window.ActiveXObject)    // IE
        {
            return xmlDoc.transformNode(xslDoc);
        }
        else    // FireFox, Chrome
        {
            //定义XSLTProcesor对象
            var xsltProcessor = new XSLTProcessor();
            xsltProcessor.importStylesheet(xslDoc);
            // transformToDocument方式
            var result = xsltProcessor.transformToDocument(xmlDoc);
            var xmls = new XMLSerializer();
            var rt = xmls.serializeToString(result);
            return rt;
        }
    }

    //获取ie的xml加载控件
    function GetXmlDocObject() {
        var xmldoc;
        try {
            xmldoc = new ActiveXObject("Msxml2.DOMDocument");
        }
        catch (e) {
            try {
                xmldoc = new ActiveXObject("Microsoft.XMLDOM");
            }
            catch (E) {
                xmldoc = false;
            }
        }
        return xmldoc;
    }

    // 得到节点的文本
    function xml_text(xmlNode) {
        if (null == xmlNode) return "";
        var rt;
        if (window.ActiveXObject)    // IE
        {
            rt = xmlNode.text;
        }
        else {
            // FireFox, Chrome, ...
            rt = xmlNode.textContent;
        }
        if (null == rt) rt = xmlNode.nodeValue;    // XML DOM
        return rt;
    }

    var str = /^\s*</;
    if (document.recalc || window.ActiveXObject ) { // IE 5+
        $.fn.xslt = function (xml, xslt, callback) {//, callback
            var target = $(this);
            var xm = GetXmlDocObject();

            xm.async = false;
            xm.loadXML(xml);

            try
            {
                //裝載樣式
                var xslDoc = GetXmlDocObject();;
                xslDoc.async = false;
                xslDoc.resolveExternals = false;
                xslDoc.load(xslt);
                target.html(xm.transformNode(xslDoc));
                if (typeof (callback) === 'function')
                    callback.apply(this);
            }
            catch (E) {
                $.get(xslt, function (data) {
                    target.html(xm.transformNode(data));
                    if (typeof (callback) === 'function')
                        callback.apply(this);
                });
            }
            return this;
        };
    }
    else if (window.DOMParser != undefined && window.XSLTProcessor != undefined) //针对其Chrome
    {
        $.fn.xslt = function (xml, xslt, callback) {//,callback         
            var target = $(this);
            //针对chrome
            var xmlDoc = loadXmlForChrome(xml);
            var xsltLoad = loadXML(xslt);
            var strResult = xml_transformNode(xmlDoc, xsltLoad);
            target.html(strResult);

            if (typeof (callback) === 'function')
                callback.apply(this);
              
            return this;
        };
    }
    else if (window.DOMParser != undefined && window.XMLHttpRequest != undefined && window.XSLTProcessor != undefined) { // Mozilla 0.9.4+, Opera 9+
        var processor = new XSLTProcessor();
        var support = false;
        if ($.isFunction(processor.transformDocument)) {
            support = window.XMLSerializer != undefined;
        }
        else {
            support = true;
        }
        if (support) {
            $.fn.xslt = function (xml, xslt, callback) {
                var target = $(this);
                var transformed = false;
                var xm = {
                    readyState: 4
                };
                var xs = {
                    readyState: 4
                };

                var change = function () {
                    if (xm.readyState == 4 && xs.readyState == 4 && !transformed) {
                        var processor = new XSLTProcessor();
                        if ($.isFunction(processor.transformDocument)) {
                            // obsolete Mozilla interface
                            resultDoc = document.implementation.createDocument("", "", null);
                            processor.transformDocument(xm.responseXML, xs.responseXML, resultDoc, null);
                            target.html(new XMLSerializer().serializeToString(resultDoc));
                        }
                        else {
                            processor.importStylesheet(xs.responseXML);
                            resultDoc = processor.transformToFragment(xm.responseXML, document);
                            target.empty().append(resultDoc);
                        }
                        transformed = true;

                        if (typeof (callback) === 'function') callback.apply(this);
                    }
                };

                if (str.test(xml)) {
                    xm.responseXML = new DOMParser().parseFromString(xml, "text/xml");
                }
                else {
                    xm = $.ajax({ dataType: "xml", url: xml });
                    xm.onreadystatechange = change;
                }

                //针对chrome等其他浏览器
                if (str.test(xslt)) {
                    xs.responseXML = new DOMParser().parseFromString(xslt, "text/xml");
                    change();
                }
                else {
                    xs = $.ajax({ dataType: "xml", url: xslt });
                    xs.onreadystatechange = change;
                }

                return this;
            };

        }
    }
    
})(jQuery);